var fm_uploader;

function fm_uploadFiles(_dir, _input) {
	files = _input.files;
	_input.files = null;
	if (files != null && files.length > 0) {
		fm_uploader = new fm_Uploader(_dir, files);
		setTimeout("fm_uploader.goBaby();", 10);
	}
}

function fm_Uploader(_dir, _fileList) {
	this.MAX_SLICE = 2048 * 1024;
	this.MIN_SLICE = 2048;
	this.SLICING_NONE = 1;
	this.SLICING_WEBKIT = 2;
	this.SLICING_MOZ = 3;
	this.SLICING_PURE = 4
	this.REPLACE = 1;
	this.APPEND = 2;
	this.SKIP = 3;
	this.appendMode = 0;
	this.slice;
	this.fileIndex = 0;
	this.sliceStart;
	this.fileList = _fileList;
	this.dir = _dir;
	this.fileName;
	this.fileSize;
	this.fileUploaded;
	this.file;
	this.totalSize = 0;
	this.totalUploaded = 0;
	this.taskProgress;
	this.errors = 0;
	this.blob;
	this.xhr;
	this.slicing;
	this.existings = new Array();
	this.anyExistings = false;
	this.adler32 = new Adler32();
	this.sentTime = 0;

	this.goBaby = function() {
		var req = new XMLHttpRequest();
		req.onreadystatechange = function() {
			if (req.readyState == 4 && req.status == 200) {
				addPing(new Date().getTime() - req.uploader.sentTime);
				var lsDir = main_readJSONResponse(req);
				var list = lsDir.ls;
				for ( var item in list) {
					var existing = list[item];
					var index = existing.path.lastIndexOf("/");
					var name = existing.path.substring(index + 1);
					req.uploader.existings[name] = existing;
					for ( var i = 0; i < req.uploader.fileList.length; i++) {
						if (req.uploader.existings[req.uploader.fileList[i].name]) {
							req.uploader.anyExistings = true;
						} else {
							req.uploader.existings[req.uploader.fileList[i].name] = null;
						}
					}
				}
				if (req.uploader.anyExistings) {
					popup_show('Overwrite menu', fm_popupOverwrite,
							'fm_overwrite');
				} else {
					fm_append = false;
					req.uploader.startUpload();
				}
			}
		}
		req.uploader = this;
		main_encryptReq(req, "fm", this.dir);
		this.sentTime = new Date().getTime();
	}

	this.startReplace = function() {
		this.appendMode = this.REPLACE;
		this.startUpload();
	}
	this.startAppend = function() {
		this.appendMode = this.APPEND;
		this.startUpload();
	}
	this.startSkip = function() {
		this.appendMode = this.SKIP;
		this.startUpload();
	}
	this.startUpload = function() {
		popup_hide('fm_overwrite');
		for ( var i = 0; i < this.fileList.length; i++) {
			this.totalSize += this.fileList[i].size;
		}
		var barCount = (this.fileList.length > 1) ? 2 : 1;
		var title = "";
		if (this.fileList.length > 1) {
			title = _T("Uploading") + ": " + this.fileList.length + " " + _T("files")
					+ ". " + _T("Destination") + ": " + this.dir;
		} else {
			title = _T("Uploading") + ": " + this.fileList[0].name + ". "
					+ _T("Destination") + ": " + this.dir;
		}
		// FIXME THERE
		this.taskProgress = new tasks_Task(title, barCount);
		this.xhr = new XMLHttpRequest();
		this.xhr.timeout = 30000;
		this.xhr.addEventListener("timeout", this.handleTimeout, false);
		this.xhr.addEventListener("load", this.handleLoad, false);
		this.xhr.addEventListener("error", this.handleError, false);
		this.xhr.addEventListener("abort", this.handleAbort, false);
		this.xhr.uploader = this;
		// HTML5 uniformity example ;-)
		var testFile = this.fileList[0];
		//testFile=new Object();
		if (testFile.slice) {
			this.slicing = this.SLICING_PURE;
		} else if (testFile.webkitSlice) {
			this.slicing = this.SLICING_WEBKIT;
		} else if (testFile.mozSlice) {
			this.slicing = this.SLICING_MOZ;
		} else {
			this.slicing = this.SLICING_NONE;
			popup_show(_T("NoSlicing"), fm_popupNoSlicing,
			'fm_noSlicingPopup', "20em");
		}
		this.uploadFile();
	};

	this.uploadFile = function() {
		if (this.fileIndex < this.fileList.length) {
			this.file = this.fileList[this.fileIndex];
			this.fileName = this.dir + "/" + this.file.name;
			this.fileSize = this.file.size;
			this.sliceStart = 0;
			this.fileUploaded = 0;
			if ((this.appendMode != this.REPLACE) && this.anyExistings) {
				if (this.existings[this.file.name] != null) {
					if (this.appendMode == this.APPEND) {
						this.sliceStart = this.existings[this.file.name].size;
					} else {// SKIP
						this.sliceStart = this.fileSize;
					}
					this.totalUploaded += this.sliceStart;
					this.fileUploaded = this.sliceStart;
				}
			}
			if (this.fileUploaded < this.fileSize) {
				if (this.slicing != this.SLICING_NONE) {
					this.slice = this.fileSize / 10;
					this.slice = Math.min(this.MAX_SLICE, Math.max(
							this.MIN_SLICE, this.slice));
					this.nextSlice();
				} else {
					var p_file = "?file=" + this.fileName;
					var p_position = "&position=0";
					var p_adlerA = "&adlerA=-1";
					var p_adlerB = "&adlerB=-1";
					this.xhr.open("post", "/fm_clearupload" + p_file
							+ p_position + p_adlerA + p_adlerB, true);
					this.blob = this.file
					this.xhr.send(this.blob);
				}
			} else {
				this.taskProgress
						.update([ [ this.fileSize, this.fileUploaded ],
								[ this.totalSize, this.totalUploaded ] ],
								this.fileName);
				this.fileIndex++;
				this.uploadFile();
			}
		} else {
			this.taskProgress.update([ [ this.fileSize, this.fileUploaded ],
					[ this.totalSize, this.totalUploaded ] ],
					"<span style=\"color:#99ff99;\">" + _T("Finished") + "</span>");
		}
	};

	this.nextSlice = function() {
		// HTML5 uniformity example ;-)
		if (this.slicing == this.SLICING_PURE) {
			this.blob = this.file.slice(this.sliceStart, this.sliceStart
					+ this.slice);
		} else if (this.slicing == this.SLICING_WEBKIT) {
			this.blob = this.file.webkitSlice(this.sliceStart, this.sliceStart
					+ this.slice);
		} else if (this.slicing == this.SLICING_MOZ) {
			this.blob = this.file.mozSlice(this.sliceStart, this.sliceStart
					+ this.slice);
		}
		var reader = new FileReader();
		reader.uploader = this;
		reader.onloadend = function() {
			var ui8ArrayView = new Uint8Array(this.result);
			this.uploader.sendSlice(ui8ArrayView);
		};
		reader.readAsArrayBuffer(this.blob);
	}

	this.sendSlice = function(_arrayView) {
		this.adler32.reset();
		this.adler32.update(_arrayView);
		/*
		 * var data=new Object(); data.filename=this.fileName;
		 * data.position=this.sliceStart; data.adlerA=this.adler32.getValueA();
		 * data.adlerB=this.adler32.getValueB(); data.data=this.blob;
		 */
		var p_file = "?file=" + this.fileName;
		var p_position = "&position=" + this.sliceStart;
		var p_adlerA = "&adlerA=" + this.adler32.getValueA();
		var p_adlerB = "&adlerB=" + this.adler32.getValueB();
		this.xhr.open("post", "/fm_clearupload" + p_file + p_position
				+ p_adlerA + p_adlerB, true);
		// alert(debugObject(this.blob));
		this.xhr.send(this.blob);
		// main_encryptReq(xhr,"fm_upload",data);
	}

	this.handleLoad = function() {
		var uploader = this.uploader;
		var fileInfo = main_readJSONResponse(uploader.xhr);
		uploader.totalUploaded+=fileInfo.file.size-uploader.fileUploaded;
		//alert(uploader.totalUploaded);
		uploader.fileUploaded = fileInfo.file.size;
		uploader.sliceStart = uploader.fileUploaded;
		uploader.blob = null;
		uploader.taskProgress.update([
				[ uploader.fileSize, uploader.fileUploaded ],
				[ uploader.totalSize, uploader.totalUploaded ] ],
				uploader.fileName);
		if (fm_requiredPath == uploader.dir) {
			fm_innerLs(fm_requiredPath);
		}
		if (uploader.sliceStart < uploader.fileSize) {
			uploader.nextSlice();
		} else {
			uploader.fileIndex++;
			uploader.uploadFile();
		}
	};

	

	this.handleError = function() {
		var uploader = this.uploader;
		uploader.blob = null;
		uploader.errors++;
		// uploader.fileInfo = eval("(" + this.responseText + ")");
		uploader.taskProgress.update([
				[ uploader.fileSize, uploader.fileUploaded ],
				[ uploader.totalSize, uploader.totalUploaded ] ],
				"<span style=\"color:#ff9999;\">" + uploader.fileName + " "
						+ _T("Failed") + "</span>");
	};

	this.handleTimeout = this.handleError;

	this.handleAbort = this.handleError;
}
